package co.fitstart.market.web.interceptor;

import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.WebUtils;

import co.fitstart.entity.market.MarketCourseRound;
import co.fitstart.entity.market.MarketInvitationRecord;
import co.fitstart.entity.user.User;
import co.fitstart.market.Constant;
import co.fitstart.market.service.MarketCourseRoundService;
import co.fitstart.market.service.MarketInvitationRecordService;
import co.fitstart.market.service.UserService;

/**
 * 
 * @author dan
 *
 */
public class ParticipateDetectInterceptor extends HandlerInterceptorAdapter {
    
    private static final Logger logger = LoggerFactory.getLogger(ParticipateDetectInterceptor.class);
    
    @Autowired
    private MarketCourseRoundService marketCourseRoundService;
    
    @Autowired
    private MarketInvitationRecordService marketInvitationRecordService;
    
    @Autowired
    private UserService userService;
    
    /**
     * wechat openid key
     */
    private String openidKey = Constant.OPENID_KEY;
    
    /**
     * system host path
     */
    private String hostPath;
    
    /**
     * if user hasn't participated redirect to participate url
     */
    private String participateUrl;
    
    /**
     * if user hasn't invited three person redirect to questionnaire url
     */
    private String questionnaireUrl;
    
    /**
     * HostPath the hostPath to set
     * @param hostPath
     */
    public void setHostPath(String hostPath) {
        this.hostPath = hostPath;
    }
    
    /**
     *  participateUrl the participateUrl to set
     * @param participateUrl
     */
    public void setParticipateUrl(String participateUrl) {
        this.participateUrl = participateUrl;
    }
    
    /**
     *  questionnaireUrl the questionnaireUrl to set
     * @param questionnaireUrl
     */
    public void setQuestionnaireUrl(String questionnaireUrl) {
        this.questionnaireUrl = questionnaireUrl;
    }
    
    /*
     * (non-Javadoc)
     * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        
        if (handler instanceof HandlerMethod) {
            
            if(logger.isDebugEnabled()) {
                logger.debug("ParticipateDetectInterceptor#preHandle - whether user participate .. ");
            }
            
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            
            ParticipateDetect participateDetect = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), ParticipateDetect.class);
            
            // Check1 participateDetect ---- if without participateDetect or participateDetect property ignore is true, return super preHandle
            if(participateDetect == null || participateDetect.ignore()) {
                logger.info("ParticipateDetectInterceptor#preHandle - RETURN SUPER_PREHANLDER ---------------- (participateDetect is null or participateDetect ignore is true)");
                return super.preHandle(request, response, handler);
            }
                        
            // Begin ---- start check and deside go to mobile or pc
            logger.info("ParticipateDetectInterceptor#preHandle - ############################Begin SigninDetectInterceptor.");
            
            // 1 get origin request url from http servlet request
            String requestUrl = request.getRequestURL().toString();
            logger.info("ParticipateDetectInterceptor#preHandle - get origin request url [" + requestUrl + "]");
            
            // 2. generate participate url by router & config properities (router's participateUrl > config properity's participateUrl > config properity's websiteHost)
            String participateUrl = StringUtils.isBlank(participateDetect.participateUrl()) ? this.participateUrl : participateDetect.participateUrl();

            // 3. generate questionnaire url by router & config properities (router's questionnaireUrl > config properity's questionnaireUrl > config properity's websiteHost)
            String questionnaireUrl = StringUtils.isBlank(participateDetect.questionnaireUrl()) ? this.questionnaireUrl : participateDetect.questionnaireUrl();
            
            logger.info("ParticipateDetectInterceptor#preHandle - get participate url [" + participateUrl + "] - get questionnaire url [" + questionnaireUrl + "]");
            
            // 4. get user
            Cookie openidCookie = WebUtils.getCookie(request, openidKey);
            User user = userService.getUserByOpenId(openidCookie.getValue());
            
            // 5. if user is not null get user's courseRound
            if (user != null) {
                MarketCourseRound courseRound = marketCourseRoundService.load(user);
                
                // if courseRound is null redirect to participateUrl
                if(courseRound == null) {
                    response.sendRedirect(hostPath + "/" + participateUrl);
                    return false;
                } else {
                    // if user doesn't invite three person redirect to questionnaireUrl
                    List<MarketInvitationRecord> invitationRecords = marketInvitationRecordService.list(user.getOpenid());
                    if(invitationRecords.size() < 1) {
                        response.sendRedirect(hostPath + "/" + questionnaireUrl);
                        return false;
                    }
                }
            }
            
        }
        
        return super.preHandle(request, response, handler);
    }
}
